{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Convolutional Neural Networks\n",
    "(c) Deniz Yuret, 2019\n",
    "* Objectives: See the effect of sparse and shared weights implemented by convolutional networks.\n",
    "* Prerequisites: [MLP models](40.mlp.ipynb), [MNIST](20.mnist.ipynb)\n",
    "* New functions:\n",
    "[conv4](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.conv4),\n",
    "[pool](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.pool),\n",
    "[mat](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.mat)\n",
    "\n",
    "![image](https://github.com/denizyuret/Knet.jl/blob/master/docs/src/images/le_net.png?raw=true)\n",
    "([image source](http://www.dataiku.com/blog/2015/08/18/Deep_Learning.html))\n",
    "\n",
    "To improve the performance further, we can use a convolutional neural networks (CNN). See the [course notes](http://cs231n.github.io/convolutional-networks/) by Andrej Karpathy for a good introduction to CNNs. We will implement the [LeNet](http://yann.lecun.com/exdb/lenet) model which consists of two convolutional layers followed by two fully connected layers. We will describe and use the [conv4](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.conv4) and [pool](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.pool) functions provided by Knet for the implementation of convolutional nets.\n",
    "\n",
    "Even though MLPs and CNNs are both universal function approximators and both achieve 0 error on the training set, we will see that a CNN converges a lot faster and generalizes a lot better with less overfitting achieving a 99.5% test accuracy on MNIST. The sparse connectivity and shared weights of a CNN give it an inductive bias appropriate for image features allowing it to learn better with less data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Setup display width, load packages, import symbols\n",
    "ENV[\"COLUMNS\"]=72\n",
    "using Pkg; for p in (\"Knet\",\"Plots\"); haskey(Pkg.installed(),p) || Pkg.add(p); end\n",
    "using Base.Iterators: flatten\n",
    "using Statistics: mean\n",
    "using Knet: Knet, conv4, pool, mat, KnetArray, nll, zeroone, progress, sgd, param, param0, dropout, relu, Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Introduction to convolution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/latex": [
       "\\begin{verbatim}\n",
       "conv4(w, x; kwargs...)\n",
       "\\end{verbatim}\n",
       "Execute convolutions or cross-correlations using filters specified with \\texttt{w} over tensor \\texttt{x}.\n",
       "\n",
       "Currently KnetArray\\{Float32/64,4/5\\} and Array\\{Float32/64,4\\} are supported as \\texttt{w} and \\texttt{x}.  If \\texttt{w} has dimensions \\texttt{(W1,W2,...,I,O)} and \\texttt{x} has dimensions \\texttt{(X1,X2,...,I,N)}, the result \\texttt{y} will have dimensions \\texttt{(Y1,Y2,...,O,N)} where\n",
       "\n",
       "\\begin{verbatim}\n",
       "Yi=1+floor((Xi+2*padding[i]-Wi)/stride[i])\n",
       "\\end{verbatim}\n",
       "Here \\texttt{I} is the number of input channels, \\texttt{O} is the number of output channels, \\texttt{N} is the number of instances, and \\texttt{Wi,Xi,Yi} are spatial dimensions.  \\texttt{padding} and \\texttt{stride} are keyword arguments that can be specified as a single number (in which case they apply to all dimensions), or an array/tuple with entries for each spatial dimension.\n",
       "\n",
       "\\section{Keywords}\n",
       "\\begin{itemize}\n",
       "\\item \\texttt{padding=0}: the number of extra zeros implicitly concatenated at the start and at the end of each dimension.\n",
       "\n",
       "\n",
       "\\item \\texttt{stride=1}: the number of elements to slide to reach the next filtering window.\n",
       "\n",
       "\n",
       "\\item \\texttt{upscale=1}: upscale factor for each dimension.\n",
       "\n",
       "\n",
       "\\item \\texttt{mode=0}: 0 for convolution and 1 for cross-correlation.\n",
       "\n",
       "\n",
       "\\item \\texttt{alpha=1}: can be used to scale the result.\n",
       "\n",
       "\n",
       "\\item \\texttt{handle}: handle to a previously created cuDNN context. Defaults to a Knet allocated handle.\n",
       "\n",
       "\\end{itemize}\n"
      ],
      "text/markdown": [
       "```\n",
       "conv4(w, x; kwargs...)\n",
       "```\n",
       "\n",
       "Execute convolutions or cross-correlations using filters specified with `w` over tensor `x`.\n",
       "\n",
       "Currently KnetArray{Float32/64,4/5} and Array{Float32/64,4} are supported as `w` and `x`.  If `w` has dimensions `(W1,W2,...,I,O)` and `x` has dimensions `(X1,X2,...,I,N)`, the result `y` will have dimensions `(Y1,Y2,...,O,N)` where\n",
       "\n",
       "```\n",
       "Yi=1+floor((Xi+2*padding[i]-Wi)/stride[i])\n",
       "```\n",
       "\n",
       "Here `I` is the number of input channels, `O` is the number of output channels, `N` is the number of instances, and `Wi,Xi,Yi` are spatial dimensions.  `padding` and `stride` are keyword arguments that can be specified as a single number (in which case they apply to all dimensions), or an array/tuple with entries for each spatial dimension.\n",
       "\n",
       "# Keywords\n",
       "\n",
       "  * `padding=0`: the number of extra zeros implicitly concatenated at the start and at the end of each dimension.\n",
       "  * `stride=1`: the number of elements to slide to reach the next filtering window.\n",
       "  * `upscale=1`: upscale factor for each dimension.\n",
       "  * `mode=0`: 0 for convolution and 1 for cross-correlation.\n",
       "  * `alpha=1`: can be used to scale the result.\n",
       "  * `handle`: handle to a previously created cuDNN context. Defaults to a Knet allocated handle.\n"
      ],
      "text/plain": [
       "\u001b[36m  conv4(w, x; kwargs...)\u001b[39m\n",
       "\n",
       "  Execute convolutions or cross-correlations using filters specified\n",
       "  with \u001b[36mw\u001b[39m over tensor \u001b[36mx\u001b[39m.\n",
       "\n",
       "  Currently KnetArray{Float32/64,4/5} and Array{Float32/64,4} are\n",
       "  supported as \u001b[36mw\u001b[39m and \u001b[36mx\u001b[39m. If \u001b[36mw\u001b[39m has dimensions \u001b[36m(W1,W2,...,I,O)\u001b[39m and \u001b[36mx\u001b[39m has\n",
       "  dimensions \u001b[36m(X1,X2,...,I,N)\u001b[39m, the result \u001b[36my\u001b[39m will have dimensions\n",
       "  \u001b[36m(Y1,Y2,...,O,N)\u001b[39m where\n",
       "\n",
       "\u001b[36m  Yi=1+floor((Xi+2*padding[i]-Wi)/stride[i])\u001b[39m\n",
       "\n",
       "  Here \u001b[36mI\u001b[39m is the number of input channels, \u001b[36mO\u001b[39m is the number of output\n",
       "  channels, \u001b[36mN\u001b[39m is the number of instances, and \u001b[36mWi,Xi,Yi\u001b[39m are spatial\n",
       "  dimensions. \u001b[36mpadding\u001b[39m and \u001b[36mstride\u001b[39m are keyword arguments that can be\n",
       "  specified as a single number (in which case they apply to all\n",
       "  dimensions), or an array/tuple with entries for each spatial\n",
       "  dimension.\n",
       "\n",
       "\u001b[1m  Keywords\u001b[22m\n",
       "\u001b[1m  ≡≡≡≡≡≡≡≡≡≡\u001b[22m\n",
       "\n",
       "    •    \u001b[36mpadding=0\u001b[39m: the number of extra zeros implicitly\n",
       "        concatenated at the start and at the end of each\n",
       "        dimension.\n",
       "\n",
       "    •    \u001b[36mstride=1\u001b[39m: the number of elements to slide to reach the\n",
       "        next filtering window.\n",
       "\n",
       "    •    \u001b[36mupscale=1\u001b[39m: upscale factor for each dimension.\n",
       "\n",
       "    •    \u001b[36mmode=0\u001b[39m: 0 for convolution and 1 for cross-correlation.\n",
       "\n",
       "    •    \u001b[36malpha=1\u001b[39m: can be used to scale the result.\n",
       "\n",
       "    •    \u001b[36mhandle\u001b[39m: handle to a previously created cuDNN context.\n",
       "        Defaults to a Knet allocated handle."
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution operator in Knet\n",
    "@doc conv4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = [1.0; 2.0; 3.0]\n",
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y = conv4(w, x) = [10.0; 16.0; 22.0; 28.0; 34.0]\n"
     ]
    }
   ],
   "source": [
    "# Convolution in 1-D\n",
    "w = reshape([1.0,2.0,3.0], (3,1,1,1)); @show w\n",
    "x = reshape([1.0:7.0...], (7,1,1,1)); @show x\n",
    "@show y = conv4(w, x);  # size Y = X - W + 1 = 5 by default"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = [1.0; 2.0; 3.0]\n",
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y2 = conv4(w, x, padding=(1, 0)) = [4.0; 10.0; 16.0; 22.0; 28.0; 34.0; 32.0]\n"
     ]
    }
   ],
   "source": [
    "# Padding\n",
    "w = reshape([1.0,2.0,3.0], (3,1,1,1)); @show w\n",
    "x = reshape([1.0:7.0...], (7,1,1,1)); @show x\n",
    "@show y2 = conv4(w, x, padding=(1,0));  # size Y = X + 2P - W + 1 = 7 with padding=1\n",
    "# To preserve input size (Y=X) for a given W, what padding P should we use?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = [1.0; 2.0; 3.0]\n",
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y3 = conv4(w, x; padding=(1, 0), stride=3) = [4.0; 22.0; 32.0]\n"
     ]
    }
   ],
   "source": [
    "# Stride\n",
    "w = reshape([1.0,2.0,3.0], (3,1,1,1)); @show w\n",
    "x = reshape([1.0:7.0...], (7,1,1,1)); @show x\n",
    "@show y3 = conv4(w, x; padding=(1,0), stride=3);  # size Y = 1 + floor((X+2P-W)/S)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = [1.0; 2.0; 3.0]\n",
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y4 = conv4(w, x, mode=0) = [10.0; 16.0; 22.0; 28.0; 34.0]\n",
      "y5 = conv4(w, x, mode=1) = [14.0; 20.0; 26.0; 32.0; 38.0]\n"
     ]
    }
   ],
   "source": [
    "# Mode\n",
    "w = reshape([1.0,2.0,3.0], (3,1,1,1)); @show w\n",
    "x = reshape([1.0:7.0...], (7,1,1,1)); @show x\n",
    "@show y4 = conv4(w, x, mode=0);  # Default mode (convolution) inverts w\n",
    "@show y5 = conv4(w, x, mode=1);  # mode=1 (cross-correlation) does not invert w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×3×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  4.0  7.0\n",
       " 2.0  5.0  8.0\n",
       " 3.0  6.0  9.0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution in more dimensions\n",
    "x = reshape([1.0:9.0...], (3,3,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  3.0\n",
       " 2.0  4.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w = reshape([1.0:4.0...], (2,2,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 23.0  53.0\n",
       " 33.0  63.0"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = conv4(w, x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×3×2×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  4.0  7.0\n",
       " 2.0  5.0  8.0\n",
       " 3.0  6.0  9.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 10.0  13.0  16.0\n",
       " 11.0  14.0  17.0\n",
       " 12.0  15.0  18.0"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution with multiple channels, filters, and instances\n",
    "# size X = [X1,X2,...,Xd,Cx,N] where d is the number of dimensions, Cx is channels, N is instances\n",
    "x = reshape([1.0:18.0...], (3,3,2,1)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "# size W = [W1,W2,...,Wd,Cx,Cy] where d is the number of dimensions, Cx is input channels, Cy is output channels\n",
    "w = reshape([1.0:24.0...], (2,2,2,3));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×3×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 328.0  436.0\n",
       " 364.0  472.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 808.0  1108.0\n",
       " 908.0  1208.0\n",
       "\n",
       "[:, :, 3, 1] =\n",
       " 1288.0  1780.0\n",
       " 1452.0  1944.0"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# size Y = [Y1,Y2,...,Yd,Cy,N]  where Yi = 1 + floor((Xi+2Pi-Wi)/Si), Cy is channels, N is instances\n",
    "y = conv4(w,x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "See http://cs231n.github.io/assets/conv-demo/index.html for an animated example."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Introduction to Pooling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/latex": [
       "\\begin{verbatim}\n",
       "pool(x; kwargs...)\n",
       "\\end{verbatim}\n",
       "Compute pooling of input values (i.e., the maximum or average of several adjacent values) to produce an output with smaller height and/or width.\n",
       "\n",
       "Currently 4 or 5 dimensional KnetArrays with \\texttt{Float32} or \\texttt{Float64} entries are supported.  If \\texttt{x} has dimensions \\texttt{(X1,X2,...,I,N)}, the result \\texttt{y} will have dimensions \\texttt{(Y1,Y2,...,I,N)} where\n",
       "\n",
       "\\begin{verbatim}\n",
       "Yi=1+floor((Xi+2*padding[i]-window[i])/stride[i])\n",
       "\\end{verbatim}\n",
       "Here \\texttt{I} is the number of input channels, \\texttt{N} is the number of instances, and \\texttt{Xi,Yi} are spatial dimensions.  \\texttt{window}, \\texttt{padding} and \\texttt{stride} are keyword arguments that can be specified as a single number (in which case they apply to all dimensions), or an array/tuple with entries for each spatial dimension.\n",
       "\n",
       "\\section{Keywords:}\n",
       "\\begin{itemize}\n",
       "\\item \\texttt{window=2}: the pooling window size for each dimension.\n",
       "\n",
       "\n",
       "\\item \\texttt{padding=0}: the number of extra zeros implicitly concatenated at the start and at the end of each dimension.\n",
       "\n",
       "\n",
       "\\item \\texttt{stride=window}: the number of elements to slide to reach the next pooling window.\n",
       "\n",
       "\n",
       "\\item \\texttt{mode=0}: 0 for max, 1 for average including padded values, 2 for average excluding padded values.\n",
       "\n",
       "\n",
       "\\item \\texttt{maxpoolingNanOpt=0}: Nan numbers are not propagated if 0, they are propagated if 1.\n",
       "\n",
       "\n",
       "\\item \\texttt{alpha=1}: can be used to scale the result.\n",
       "\n",
       "\n",
       "\\item \\texttt{handle}: Handle to a previously created cuDNN context. Defaults to a Knet allocated handle.\n",
       "\n",
       "\\end{itemize}\n"
      ],
      "text/markdown": [
       "```\n",
       "pool(x; kwargs...)\n",
       "```\n",
       "\n",
       "Compute pooling of input values (i.e., the maximum or average of several adjacent values) to produce an output with smaller height and/or width.\n",
       "\n",
       "Currently 4 or 5 dimensional KnetArrays with `Float32` or `Float64` entries are supported.  If `x` has dimensions `(X1,X2,...,I,N)`, the result `y` will have dimensions `(Y1,Y2,...,I,N)` where\n",
       "\n",
       "```\n",
       "Yi=1+floor((Xi+2*padding[i]-window[i])/stride[i])\n",
       "```\n",
       "\n",
       "Here `I` is the number of input channels, `N` is the number of instances, and `Xi,Yi` are spatial dimensions.  `window`, `padding` and `stride` are keyword arguments that can be specified as a single number (in which case they apply to all dimensions), or an array/tuple with entries for each spatial dimension.\n",
       "\n",
       "# Keywords:\n",
       "\n",
       "  * `window=2`: the pooling window size for each dimension.\n",
       "  * `padding=0`: the number of extra zeros implicitly concatenated at the start and at the end of each dimension.\n",
       "  * `stride=window`: the number of elements to slide to reach the next pooling window.\n",
       "  * `mode=0`: 0 for max, 1 for average including padded values, 2 for average excluding padded values.\n",
       "  * `maxpoolingNanOpt=0`: Nan numbers are not propagated if 0, they are propagated if 1.\n",
       "  * `alpha=1`: can be used to scale the result.\n",
       "  * `handle`: Handle to a previously created cuDNN context. Defaults to a Knet allocated handle.\n"
      ],
      "text/plain": [
       "\u001b[36m  pool(x; kwargs...)\u001b[39m\n",
       "\n",
       "  Compute pooling of input values (i.e., the maximum or average of\n",
       "  several adjacent values) to produce an output with smaller height\n",
       "  and/or width.\n",
       "\n",
       "  Currently 4 or 5 dimensional KnetArrays with \u001b[36mFloat32\u001b[39m or \u001b[36mFloat64\u001b[39m\n",
       "  entries are supported. If \u001b[36mx\u001b[39m has dimensions \u001b[36m(X1,X2,...,I,N)\u001b[39m, the\n",
       "  result \u001b[36my\u001b[39m will have dimensions \u001b[36m(Y1,Y2,...,I,N)\u001b[39m where\n",
       "\n",
       "\u001b[36m  Yi=1+floor((Xi+2*padding[i]-window[i])/stride[i])\u001b[39m\n",
       "\n",
       "  Here \u001b[36mI\u001b[39m is the number of input channels, \u001b[36mN\u001b[39m is the number of\n",
       "  instances, and \u001b[36mXi,Yi\u001b[39m are spatial dimensions. \u001b[36mwindow\u001b[39m, \u001b[36mpadding\u001b[39m and\n",
       "  \u001b[36mstride\u001b[39m are keyword arguments that can be specified as a single\n",
       "  number (in which case they apply to all dimensions), or an\n",
       "  array/tuple with entries for each spatial dimension.\n",
       "\n",
       "\u001b[1m  Keywords:\u001b[22m\n",
       "\u001b[1m  ≡≡≡≡≡≡≡≡≡≡≡\u001b[22m\n",
       "\n",
       "    •    \u001b[36mwindow=2\u001b[39m: the pooling window size for each dimension.\n",
       "\n",
       "    •    \u001b[36mpadding=0\u001b[39m: the number of extra zeros implicitly\n",
       "        concatenated at the start and at the end of each\n",
       "        dimension.\n",
       "\n",
       "    •    \u001b[36mstride=window\u001b[39m: the number of elements to slide to reach\n",
       "        the next pooling window.\n",
       "\n",
       "    •    \u001b[36mmode=0\u001b[39m: 0 for max, 1 for average including padded values,\n",
       "        2 for average excluding padded values.\n",
       "\n",
       "    •    \u001b[36mmaxpoolingNanOpt=0\u001b[39m: Nan numbers are not propagated if 0,\n",
       "        they are propagated if 1.\n",
       "\n",
       "    •    \u001b[36malpha=1\u001b[39m: can be used to scale the result.\n",
       "\n",
       "    •    \u001b[36mhandle\u001b[39m: Handle to a previously created cuDNN context.\n",
       "        Defaults to a Knet allocated handle."
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Pooling operator in Knet\n",
    "@doc pool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0]\n",
      "pool(x) = [2.0; 4.0; 6.0]\n"
     ]
    }
   ],
   "source": [
    "# 1-D pooling example\n",
    "x = reshape([1.0:6.0...], (6,1,1,1)); @show x\n",
    "@show pool(x);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0]\n",
      "pool(x; window=3) = [3.0; 6.0]\n"
     ]
    }
   ],
   "source": [
    "# Window size\n",
    "x = reshape([1.0:6.0...], (6,1,1,1)); @show x\n",
    "@show pool(x; window=3);  # size Y = floor(X/W)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0]\n",
      "pool(x; padding=(1, 0)) = [1.0; 3.0; 5.0; 6.0]\n"
     ]
    }
   ],
   "source": [
    "# Padding\n",
    "x = reshape([1.0:6.0...], (6,1,1,1)); @show x\n",
    "@show pool(x; padding=(1,0));  # size Y = floor((X+2P)/W)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0; 8.0; 9.0; 10.0]\n",
      "pool(x; stride=4) = [2.0; 6.0; 10.0]\n"
     ]
    }
   ],
   "source": [
    "# Stride\n",
    "x = reshape([1.0:10.0...], (10,1,1,1)); @show x\n",
    "@show pool(x; stride=4);  # size Y = 1 + floor((X+2P-W)/S)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = K[1.0; 2.0; 3.0; 4.0; 5.0; 6.0]\n",
      "pool(x; padding=(1, 0), mode=0) = K[1.0; 3.0; 5.0; 6.0]\n",
      "pool(x; padding=(1, 0), mode=1) = K[0.5; 2.5; 4.5; 3.0]\n",
      "pool(x; padding=(1, 0), mode=2) = K[1.0; 2.5; 4.5; 6.0]\n"
     ]
    }
   ],
   "source": [
    "# Mode (using KnetArray here; not all modes are implemented on the CPU)\n",
    "x = KnetArray(reshape([1.0:6.0...], (6,1,1,1))); @show x\n",
    "@show pool(x; padding=(1,0), mode=0)  # max pooling\n",
    "@show pool(x; padding=(1,0), mode=1)  # avg pooling\n",
    "@show pool(x; padding=(1,0), mode=2); # avg pooling excluding padded values (is not implemented on CPU)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  5.0   9.0  13.0\n",
       " 2.0  6.0  10.0  14.0\n",
       " 3.0  7.0  11.0  15.0\n",
       " 4.0  8.0  12.0  16.0"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# More dimensions\n",
    "x = reshape([1.0:16.0...], (4,4,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 6.0  14.0\n",
       " 8.0  16.0"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pool(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4×2×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0  5.0   9.0  13.0\n",
       " 2.0  6.0  10.0  14.0\n",
       " 3.0  7.0  11.0  15.0\n",
       " 4.0  8.0  12.0  16.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 17.0  21.0  25.0  29.0\n",
       " 18.0  22.0  26.0  30.0\n",
       " 19.0  23.0  27.0  31.0\n",
       " 20.0  24.0  28.0  32.0"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Multiple channels and instances\n",
    "x = reshape([1.0:32.0...], (4,4,2,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×2×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 6.0  14.0\n",
       " 8.0  16.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 22.0  30.0\n",
       " 24.0  32.0"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# each channel and each instance is pooled separately\n",
    "pool(x)  # size Y = (Y1,...,Yd,Cx,N) where Yi are spatial dims, Cx and N are identical to input X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Experiment setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "┌ Info: Loading MNIST...\n",
      "└ @ Main /home/deniz/.julia/dev/Knet/data/mnist.jl:33\n"
     ]
    }
   ],
   "source": [
    "# Load data (see mnist.ipynb)\n",
    "include(Knet.dir(\"data\",\"mnist.jl\"))  # Load data\n",
    "dtrn,dtst = mnistdata();              # dtrn and dtst = [ (x1,y1), (x2,y2), ... ] where xi,yi are minibatches of 100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "28×28×1×100 KnetArray{Float32,4}\n",
      "100-element Array{UInt8,1}\n"
     ]
    }
   ],
   "source": [
    "(x,y) = first(dtst)\n",
    "println.(summary.((x,y)));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "trainresults (generic function with 1 method)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# For running experiments\n",
    "function trainresults(file,model; o...)\n",
    "    if (print(\"Train from scratch? \"); readline()[1]=='y')\n",
    "        takeevery(n,itr) = (x for (i,x) in enumerate(itr) if i % n == 1)\n",
    "        r = ((model(dtrn), model(dtst), zeroone(model,dtrn), zeroone(model,dtst))\n",
    "             for x in takeevery(length(dtrn), progress(sgd(model,repeat(dtrn,100)))))\n",
    "        r = reshape(collect(Float32,flatten(r)),(4,:))\n",
    "        Knet.save(file,\"results\",r)\n",
    "        Knet.gc() # To save gpu memory\n",
    "    else\n",
    "        isfile(file) || download(\"http://people.csail.mit.edu/deniz/models/tutorial/$file\",file)\n",
    "        r = Knet.load(file,\"results\")\n",
    "    end\n",
    "    println(minimum(r,dims=2))\n",
    "    return r\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## A convolutional neural network model for MNIST"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Conv"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Define a convolutional layer:\n",
    "struct Conv; w; b; f; p; end\n",
    "(c::Conv)(x) = c.f.(pool(conv4(c.w, dropout(x,c.p)) .+ c.b))\n",
    "Conv(w1::Int,w2::Int,cx::Int,cy::Int,f=relu;pdrop=0) = Conv(param(w1,w2,cx,cy), param0(1,1,cy,1), f, pdrop)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dense"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Redefine dense layer (See mlp.ipynb):\n",
    "struct Dense; w; b; f; p; end\n",
    "(d::Dense)(x) = d.f.(d.w * mat(dropout(x,d.p)) .+ d.b) # mat reshapes 4-D tensor to 2-D matrix so we can use matmul\n",
    "Dense(i::Int,o::Int,f=relu;pdrop=0) = Dense(param(o,i), param0(o), f, pdrop)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Let's define a chain of layers\n",
    "struct Chain\n",
    "    layers\n",
    "    Chain(layers...) = new(layers)\n",
    "end\n",
    "(c::Chain)(x) = (for l in c.layers; x = l(x); end; x)\n",
    "(c::Chain)(x,y) = nll(c(x),y)\n",
    "(c::Chain)(d::Data) = mean(c(x,y) for (x,y) in d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "scrolled": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{String,1}:\n",
       " \"5×5×1×20 AutoGrad.Param{KnetArray{Float32,4}}\" \n",
       " \"5×5×20×50 AutoGrad.Param{KnetArray{Float32,4}}\"\n",
       " \"500×800 AutoGrad.Param{KnetArray{Float32,2}}\"  \n",
       " \"10×500 AutoGrad.Param{KnetArray{Float32,2}}\"   "
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lenet =   Chain(Conv(5,5,1,20), \n",
    "                Conv(5,5,20,50), \n",
    "                Dense(800,500,pdrop=0.3), \n",
    "                Dense(500,10,identity,pdrop=0.3))\n",
    "summary.(l.w for l in lenet.layers)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.2857893f0"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lenet(x,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## CNN vs MLP"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train from scratch? stdin> y\n",
      "1.08e-02  100.00%┣████████████████▉┫ 60000/60000 [03:50/03:50, 260.67i/s]\n",
      "Float32[0.000135032; 0.0196918; 0.0; 0.0053]\n"
     ]
    }
   ],
   "source": [
    "# 1.08e-02  100.00%┣████████████████▉┫ 60000/60000 [03:50/03:50, 260.67i/s]\n",
    "# [0.000135032; 0.0196918; 0.0; 0.0053]\n",
    "cnn = trainresults(\"cnn113.jld2\", lenet);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlp = Knet.load(\"mlp113f.jld2\",\"results\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "using Plots; default(fmt=:png,ls=:auto)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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"
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Comparison to MLP shows faster convergence, better generalization\n",
    "plot([mlp[1,:], mlp[2,:], cnn[1,:], cnn[2,:]],ylim=(0.0,0.1),\n",
    "     labels=[:trnMLP :tstMLP :trnCNN :tstCNN],xlabel=\"Epochs\",ylabel=\"Loss\")  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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IoqiVqv95JNP2lY99dRTkydPdq+KjIxct26deznGeM6cOZ999pn77dasWeNe7g6BBQUFhJDq6moAyM/Pd69qamr69NNPvXzoFNXv0BohRfmHOxR10H6D+fPnt/2+ePHi/Px8AGhqajIYDLfcckvbqrlz57pXGQyGhoaG7Oxs93KGYXbs2HHXXXe5/5w4caL7F5VK1fba6OjoFStWjB8/fuHCha+88ordbr/77ru9crQU1Y/RQEhR1wCGYQRB6GoVxhgA3BuwLOtxs/bxr/1r165dW1JSMmvWrOPHj2dkZDzxxBN9V2qKujbQQEhR/dTWrVvbft+0adPw4cMBICwsTKvV7tixo23V9u3b3asiIiKCg4N3797tXi6K4tixY//xj3908xZGo3HlypUhISEPP/zwhg0bNmzY8M4773jlYCiqH6PzCCnKP3788cfOQzQXLVrU9vvjjz+u0+kyMjJ27979r3/9a/PmzQCAEHryyScfeugh96p9+/a9+uqrmzZtcq96/PHHV65c2dDQkJKS8uWXX+bm5n788cfdlEGj0WzZssVqtd55550Oh2Pt2rVZWVl9f6gU1c/5vluSoqjur0f3YJnjx49PnDhRrVaPGBAzv1kAAABvSURBVDGibQgMIQRj/Prrrw8bNkypVI4aNerrr79uv+qll15KSUlRKpXjxo3btWtX29u175Js/+fhw4cnTJigUqmCg4MXL15cVVXl9YOnqH4Gka6vSYqi/KKwsHDYsGH02qQo36B9hBRFUdSg9v8BddoLdNislrsAAAAASUVORK5CYII="
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "plot([mlp[3,:], mlp[4,:], cnn[3,:], cnn[4,:]],ylim=(0.0,0.03),\n",
    "    labels=[:trnMLP :tstMLP :trnCNN :tstCNN],xlabel=\"Epochs\",ylabel=\"Error\")  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Convolution vs Matrix Multiplication"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w = reshape([1.0, 2.0, 3.0], (3, 1, 1, 1)) = [1.0; 2.0; 3.0]\n",
      "x = reshape([1.0:7.0...], (7, 1, 1, 1)) = [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0]\n",
      "y = conv4(w, x) = [10.0; 16.0; 22.0; 28.0; 34.0]\n"
     ]
    }
   ],
   "source": [
    "# Convolution and matrix multiplication can be implemented in terms of each other.\n",
    "# Convolutional networks have no additional representational power, only statistical efficiency.\n",
    "# Our original 1-D example\n",
    "@show w = reshape([1.0,2.0,3.0], (3,1,1,1))\n",
    "@show x = reshape([1.0:7.0...], (7,1,1,1))\n",
    "@show y = conv4(w, x);  # size Y = X - W + 1 = 5 by default"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5×7 Array{Float64,2}:\n",
       " 3.0  2.0  1.0  0.0  0.0  0.0  0.0\n",
       " 0.0  3.0  2.0  1.0  0.0  0.0  0.0\n",
       " 0.0  0.0  3.0  2.0  1.0  0.0  0.0\n",
       " 0.0  0.0  0.0  3.0  2.0  1.0  0.0\n",
       " 0.0  0.0  0.0  0.0  3.0  2.0  1.0"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution as matrix multiplication (1)\n",
    "# Turn w into a (Y,X) sparse matrix\n",
    "w2 = Float64[3 2 1 0 0 0 0; 0 3 2 1 0 0 0; 0 0 3 2 1 0 0; 0 0 0 3 2 1 0; 0 0 0 0 3 2 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "y2 = w2 * mat(x) = [10.0; 16.0; 22.0; 28.0; 34.0]\n"
     ]
    }
   ],
   "source": [
    "@show y2 = w2 * mat(x);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×5 Array{Float64,2}:\n",
       " 1.0  2.0  3.0  4.0  5.0\n",
       " 2.0  3.0  4.0  5.0  6.0\n",
       " 3.0  4.0  5.0  6.0  7.0"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convolution as matrix multiplication (2)\n",
    "# Turn x into a (W,Y) dense matrix (aka the im2col operation)\n",
    "# This is used to speed up convolution with known efficient matmul algorithms\n",
    "x3 = Float64[1 2 3 4 5; 2 3 4 5 6; 3 4 5 6 7]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w3 = [3.0 2.0 1.0] = [3.0 2.0 1.0]\n",
      "y3 = w3 * x3 = [10.0 16.0 22.0 28.0 34.0]\n"
     ]
    }
   ],
   "source": [
    "@show w3 = [3.0 2.0 1.0]\n",
    "@show y3 = w3 * x3;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×3 Array{Float64,2}:\n",
       " 1.0  3.0  5.0\n",
       " 2.0  4.0  6.0"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Matrix multiplication as convolution\n",
    "# This could be used to make a fully connected network accept variable sized inputs.\n",
    "w = reshape([1.0:6.0...], (2,3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×1 Array{Float64,2}:\n",
       " 1.0\n",
       " 2.0\n",
       " 3.0"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = reshape([1.0:3.0...], (3,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×1 Array{Float64,2}:\n",
       " 22.0\n",
       " 28.0"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = w * x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×1×1×2 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0\n",
       " 3.0\n",
       " 5.0\n",
       "\n",
       "[:, :, 1, 2] =\n",
       " 2.0\n",
       " 4.0\n",
       " 6.0"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Consider w with size (Y,X)\n",
    "# Treat each of the Y rows of w as a convolution filter\n",
    "w2 = copy(reshape(Array(w)', (3,1,1,2)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×1×1×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 1.0\n",
       " 2.0\n",
       " 3.0"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Reshape x for convolution\n",
    "x2 = reshape(x, (3,1,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1×1×2×1 Array{Float64,4}:\n",
       "[:, :, 1, 1] =\n",
       " 22.0\n",
       "\n",
       "[:, :, 2, 1] =\n",
       " 28.0"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Use conv4 for matrix multiplication\n",
    "y2 = conv4(w2, x2; mode=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "* So there is no difference between the class of functions representable with an MLP vs CNN.\n",
    "* Sparse connections and weight sharing give CNNs more generalization power with images.\n",
    "* Number of parameters in MLP256: (256x784)+256+(10x256)+10 = 203530\n",
    "* Number of parameters in LeNet: (5*5*1*20)+20+(5*5*20*50)+50+(500*800)+500+(10*500)+10 = 431080"
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [],
   "name": "julia.ipynb",
   "provenance": [],
   "version": "0.3.2"
  },
  "kernelspec": {
   "display_name": "Julia 1.0.3",
   "language": "julia",
   "name": "julia-1.0"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.0.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
